package com.prawn.education.service;

import java.util.*;
import java.util.concurrent.TimeUnit;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;

import com.prawn.education.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import util.IdWorker;

import com.prawn.education.dao.InformationDao;
import com.prawn.education.pojo.Information;

/**
 * 服务层
 *
 * @author Administrator
 */
@Service
public class InformationService {

    @Autowired
    private InformationDao informationDao;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IdWorker idWorker;

    /**
     * 增加
     *
     * @param information
     */
    public void add(Information information) {
        information.setId(idWorker.nextId() + "");
        information.setState(true);
        information.setCreateDate(new Date());
        informationDao.save(information);
    }

    /**
     * 修改
     *
     * @param information
     */
    public void update(Information information) {
        information.setState(true);
        information.setUpdateDate(new Date());
        informationDao.save(information);
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(String id) {
        Optional<Information> information = informationDao.findByIdAndStateTrue(id);
        information.get().setState(false);
        informationDao.save(information.get());
    }

    public Iterable<Information> findAll(int module) {
        return informationDao.findByModuleAndStateTrue(module);
    }

    public Optional<Information> findById(String informationId) {
        return informationDao.findByIdAndStateTrue(informationId);
    }

    public Optional<Information> findById(String id, String ip) {
        //key序列化方式;（不然会出现乱码;）,但是如果方法上有Long等非String类型的话，会报类型转换错误；
        //所以在没有自己定义key生成策略的时候，以下这个代码建议不要这么写，可以不配置或者自己实现ObjectRedisSerializer
//        //或者JdkSerializationRedisSerializer序列化方式;
//        RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
//        redisTemplate.setKeySerializer(redisSerializer);
//        redisTemplate.setValueSerializer(redisSerializer);
//        if (!redisTemplate.hasKey(ip + "-" + id))
//            redisTemplate.opsForValue().set(ip + "-" + id, "1");

        //ip查看学习资料id记录，设置一天过期时间,并给阅读量加1
        if (!redisUtil.hasKey(ip + ":" + id)) {
            redisUtil.set(ip + ":" + id, "1", 1, TimeUnit.DAYS);
            redisUtil.hincr("clickNum", id, 1);
        }
        return informationDao.findByIdAndStateTrue(id);
    }

    public Information findByDeleteId(String informationId) {
        return informationDao.findByIdAndStateFalse(informationId).get();
    }

    public Page<Information> findByTypeId(int module, String typeId, int page, int size) {
        return informationDao.findByModuleAndTypeIdAndStateTrue(module, typeId,PageRequest.of(page-1, size));
    }

    public Page<Information> findAll(int module, int page, int size) {
        return informationDao.findByModuleAndStateTrue(module, PageRequest.of(page-1, size));
    }

    public Page<Information> findByDelete(int module, int page, int size) {
        return informationDao.findByModuleAndStateFalse(module, PageRequest.of(page-1, size));
    }

    public Page<Information> findByTime(int module, int page, int size) {
        return informationDao.findByModuleAndStateTrueOrderByCreateDateDesc(module, PageRequest.of(page-1, size));
    }

    public Page<Information> findByTypeIdAndTime(int module, String typeId, int page, int size) {
        return informationDao.findByModuleAndTypeIdAndStateTrueOrderByCreateDateDesc(module, typeId, PageRequest.of(page-1, size));
    }

    public Page<Information> findByRecommend(int module, int page, int size) {
        return informationDao.findByModuleAndStateTrueAndRecommendTrue(module, PageRequest.of(page-1, size));
    }

    public Page<Information> findByClickNum(int module, int page, int size) {
        return informationDao.findByModuleAndStateTrueOrderByClickNumDesc(module, PageRequest.of(page-1, size));
    }

    public Page<Information> findByTypeIdAndClick(int module, String typeId, int page, int size) {
        return informationDao.findByModuleAndTypeIdAndStateTrueOrderByClickNumDesc(module, typeId, PageRequest.of(page-1, size));
    }

    public List<Information> findByTime(int module) {
        return informationDao.findByModuleAndStateTrueOrderByCreateDateDesc(module);
    }

    public List<Information> findByRecommend(int module) {
        return informationDao.findByModuleAndStateTrueAndRecommendTrue(module);
    }

    public List<Information> findByClickNum(int module) {
        return informationDao.findByModuleAndStateTrueOrderByClickNumDesc(module);
    }


}
